/**
 * 
 */
package Alibaba.AlibabaServer;

import java.util.*;
import java.util.Map.*;

/**
 * @author ronenkat
 * 
 */
public class Listing {

	/**
	 * @param listOfFiles
	 */
	public Listing(Map<String, ListingEntry> listOfFiles) {
		super();
		this.listOfFiles = listOfFiles;
	}

	/**
	 */
	public Listing() {
		super();
		this.listOfFiles = new HashMap<String, ListingEntry>();
	}

	private Map<String, ListingEntry> listOfFiles;
	private long fileCounter = 0;

	private String getKey(String userName, int snapshot, String path) {
		if (snapshot != -1) {
			return userName + '@' + snapshot + '@' + path;
		} else {
			return userName + '@' + ".*" + '@' + path;
		}
	}

	/**
	 * @return the listOfFiles
	 */
	public Map<String, ListingEntry> getListOfFiles() {
		return listOfFiles;
	}

	/**
	 * @param listOfFiles
	 *            the listOfFiles to set
	 */
	public void setListOfFiles(Map<String, ListingEntry> listOfFiles) {
		this.listOfFiles = listOfFiles;
	}

	/**
	 * Write the backup server meta information repository to disk
	 * 
	 * @param filename
	 * @param listing
	 */
	public static void writeListing(String filename, Listing listing) {
	}

	/**
	 * Read the backup server meta information repository from disk
	 * 
	 * @param filename
	 * @return
	 */
	public static Listing readListing(String filename) {
		return null;
	}

	public void addListing(String userName, int snapshotNum, String path, String localName, byte[] sha) {
		fileCounter++;
		this.listOfFiles.put(getKey(userName, snapshotNum, path), new ListingEntry(path, localName, sha, userName, snapshotNum));
	}

	public ListingEntry getListing(String userName, int snapshotNum, String path) {
		return this.listOfFiles.get(getKey(userName, snapshotNum, path));
	}

	public long getFileCounter() {
		return fileCounter;
	}

	public void setFileCounter(long fileCounter) {
		this.fileCounter = fileCounter;
	}

	public List<ListingEntry> getEntriesByPrefix(String userName, int snapshotNum, String prefix, boolean isRecursive) {
		List<ListingEntry> entries = new ArrayList<ListingEntry>();
		String key = getKey(userName, snapshotNum, prefix);
		for (Entry<String, ListingEntry> entry : listOfFiles.entrySet()) {
			if (entry.getKey().matches("^" + key + ".*")) {
				if (isRecursive || entry.getKey().lastIndexOf("/") <= key.length()) {
					entries.add(entry.getValue());
				}
			}
		}
		return entries;
	}

	public void removeKeys(String userName, int snapshotNum) {
		List<String> allKeys = new ArrayList<String>(listOfFiles.keySet());
		for (String key : allKeys) {
			if (key.startsWith(getKey(userName, snapshotNum, "/"))) {
				listOfFiles.remove(key);
			}
		}
	}

	public List<ListingEntry> getEntries() {
		return new ArrayList<ListingEntry>(listOfFiles.values());
	}

	public boolean isValidSnapshot(int snapshot) {
		return (snapshot >= 0);

	}

	public boolean isSnapshotExists(String userName, int snapshot) {
		return (getEntriesByPrefix(userName, snapshot, "/", true).size() > 0);
	}
}
